Skip to content

fs,sched: add chroot() filesystem jail - #19900

Open
Abhishekmishra2808 wants to merge 4 commits into
apache:masterfrom
Abhishekmishra2808:feature/fs-chroot
Open

fs,sched: add chroot() filesystem jail#19900
Abhishekmishra2808 wants to merge 4 commits into
apache:masterfrom
Abhishekmishra2808:feature/fs-chroot

Conversation

@Abhishekmishra2808

@Abhishekmishra2808 Abhishekmishra2808 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

CONFIG_FS_CHROOT adds POSIX chroot() so a task group can pin a directory as its filesystem root. The jail is stored as tg_root (an absolute host path, or NULL if none). Children inherit a copy via strdup; leaving the group frees it.

Lookups stay inside the jail in inode_search_setup(): join $PWD for relative paths, prepend tg_root, then canonicalize with a jail-floor dst_min so .. cannot climb out. chroot() does not rewrite PWD. chroot("/") from the host root clears the jail; from inside a jail, / is still the jail, so it cannot be used to escape.

This is a filesystem jail, not a container: descriptors opened before chroot() that already point outside the tree remain usable, and the new root is not populated with /dev or /proc.

Impact

The option is off by default. When enabled, chroot() is a new syscall and, with SCHED_USER_IDENTITY, requires effective UID 0. Companion apps change: apache/nuttx-apps#3735 (merged).

Testing

Host: WSL2 x86_64. Board: sim (CONFIG_FS_CHROOT=y). Companion apps: apache/nuttx-apps#3735.

$ ./tools/checkpatch.sh -c -u -m -g HEAD~4...HEAD
✔️ All checks pass.
$ make -j$(nproc)
LD:  nuttx

NSH jail session (syscall from userspace; chroot builtin from apache/nuttx-apps#3735):

nsh> mkdir /tmp/jail
nsh> echo hello > /tmp/jail/marker
nsh> chroot /tmp/jail
nsh> pwd
/
nsh> ls /
/:
 marker
nsh> cat /marker
hello
nsh> ls /dev
nsh: ls: stat failed: 2
nsh> cd ..
nsh> pwd
/
nsh> ls /../etc
nsh: ls: stat failed: 2
nsh> chroot /
nsh> ls /
/:
 marker

Comment thread Documentation/applications/nsh/commands.rst
Comment thread Documentation/implementation/chroot.rst Outdated
Comment thread Documentation/implementation/chroot.rst
Comment thread Documentation/implementation/chroot.rst Outdated
Comment thread Documentation/implementation/user_identity.rst Outdated
Comment thread fs/inode/fs_inodesearch.c
@acassis

acassis commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Nice work @Abhishekmishra2808 !
@xiaoxiang781216 @raiden00pl maybe we could use it to create separated jails/arenas to use with telnet / ssh to avoid user to damage the original root filesystems. But I think in this case we need to be able to mount a limited /dev, /proc, etc

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

arduino-mega2560

  • flash: .text +176 B (+0.3%, 65,268 B / 262,144 B, total: 25% used)

esp32-devkitc

  • ROM: .flash.text +88 B (+0.1%, 124,988 B / 4,194,272 B, total: 3% used)
  • irom0_0_seg: .flash.text +88 B (+0.1%, 89,192 B / 3,342,304 B, total: 3% used)

hifive1-revb

  • flash: .text +108 B (+0.1%, 83,824 B / 4,194,304 B, total: 2% used)

mirtoo

  • kseg0_progmem: .text +120 B (+0.2%, 67,872 B / 131,072 B, total: 52% used)

qemu-armv8a

  • Code: .text.file_mq_unlink -4 B, .text.file_mq_vopen -8 B, .text.file_vopen -4 B, .text.find_blockdriver -4 B, .text.inode_find +20 B, .text.inode_reserve +8 B, .text.inode_search -496 B, .text.mkdir -4 B, .text.nx_stat -4 B, .text.nx_umount2 +16 B, .text.nx_unlink -20 B, .text.rename +72 B, .text.rmdir -20 B (+0.1%, 337,708 B)

qemu-intel64

  • Code: .text -226 B (-0.0%, 8,659,488 B)
  • Data: .rodata +32 B (+0.0%, 120,177 B)

rx65n-rsk2mb

  • ROM: .text +48 B (+0.1%, 86,928 B / 2,097,152 B, total: 4% used)

s698pm-dkit

  • Code: .text +336 B (+0.1%, 365,504 B)

stm32-nucleo-f103rb

  • flash: .text +72 B (+0.2%, 34,472 B / 131,072 B, total: 26% used)

Comment thread include/nuttx/fs/fs.h Outdated
Comment thread sched/group/group_create.c
Comment thread sched/group/group_create.c Outdated
Comment thread fs/vfs/fs_chroot.c Outdated
Comment thread sched/group/group_create.c Outdated
Comment thread fs/vfs/fs_chroot.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread include/nuttx/sched.h Outdated
Comment thread fs/vfs/fs_chroot.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the feature/fs-chroot branch 2 times, most recently from 5b250cc to d3ea539 Compare August 24, 2026 03:39
Comment thread sched/group/group_create.c Outdated
Comment thread sched/group/group_create.c Outdated
@Abhishekmishra2808

Copy link
Copy Markdown
Contributor Author

@acassis PTAL !

acassis
acassis previously approved these changes Aug 24, 2026
@acassis

acassis commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Comment thread fs/vfs/fs_chroot.c Outdated
Comment thread fs/vfs/fs_chroot.c Outdated
Comment thread fs/vfs/fs_chroot.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
@xiaoxiang781216

xiaoxiang781216 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

ci was fixed, please rebase your change to the last master. @Abhishekmishra2808, many code can be simplified with #19991.

@Abhishekmishra2808

Copy link
Copy Markdown
Contributor Author

@xiaoxiang781216 done

@xiaoxiang781216

Copy link
Copy Markdown
Contributor

@xiaoxiang781216 done

@Abhishekmishra2808 please fix the conflict.

Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
@github-actions github-actions Bot added Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. and removed Size: L The size of the change in this PR is large labels Aug 29, 2026
Comment thread fs/driver/fs_findblockdriver.c Outdated
Comment thread fs/driver/fs_finddriver.c Outdated
Comment thread fs/driver/fs_findmtddriver.c Outdated
Comment thread fs/event/event_open.c Outdated
Comment thread fs/fat/fs_fat32attrib.c Outdated
Comment thread fs/mount/fs_automount.c Outdated
Comment thread fs/inode/inode.h Outdated
Comment thread fs/inode/inode.h Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/vfs/fs_chroot.c Outdated
Store the jail as an absolute path on the task group, copy it to
children, and free it when the last member leaves.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Add CONFIG_FS_CHROOT and POSIX chroot(). Store the jail as an
absolute path on the task group, and require euid 0 when user
identity is enabled.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Comment thread fs/driver/fs_findblockdriver.c Outdated
Comment thread fs/driver/fs_findmtddriver.c Outdated
Comment thread fs/inode/fs_inodefind.c
Comment thread fs/vfs/fs_symlink.c Outdated
Comment thread fs/vfs/fs_symlink.c Outdated
Comment thread fs/vfs/fs_rename.c
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
Comment thread fs/inode/fs_inodesearch.c Outdated
acassis
acassis previously approved these changes Sep 2, 2026
Prepare paths in inode_search_setup(): prepend tg_root, canonicalize
with a jail-floor dst_min, then walk from g_root_inode. Replace
SETUP_SEARCH / RELEASE_SEARCH with inode_search_setup() /
inode_search_release().

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Describe the jail, leftover pre-opened fds, the NSH command-form scrub,
and the flat-build trust boundary shared with credentials.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Comment thread fs/vfs/CMakeLists.txt
fs_truncate.c
fs_link.c)

if(CONFIG_FS_CHROOT)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this patch after fs: start absolute lookups at the jail root

Comment thread fs/vfs/fs_chroot.c Outdated
return OK;
}

newroot = strdup(abspath);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fs_heap_strdup

Comment thread fs/mount/fs_automount.c
@@ -440,7 +446,7 @@ static int automount_findinode(FAR const char *path)
/* Relinquish our exclusive access to the inode try and return the result */

inode_runlock();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need release inode

Comment thread fs/vfs/fs_rename.c
}
else
{
newinode = NULL;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why zero again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Documentation Improvements or additions to documentation Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants